package org.leon;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.UnsupportedEncodingException;
import java.util.List;


public class ZkApi implements Watcher {

    private static ZooKeeper zooKeeper;
    private static boolean initFlag = false;

    public static void main(String[] args) throws Exception {
        /*
            使用 zk 的 api 连接 zk 是个异步的过程, 基本都是靠注册的 Watcher 进行处理的
         */
        zooKeeper = new ZooKeeper("127.0.0.1:2181", 5000, new ZkApi());
        Thread.sleep(Integer.MAX_VALUE);
    }

    public void process(WatchedEvent watchedEvent) {
        if (watchedEvent.getState() == Event.KeeperState.SyncConnected && !initFlag) {
            // 连接建立成功后, 进行后续操作
            try {
                createNode();
                System.out.println("create a node successfully");
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            initFlag = true;
        }

        // 节点的字节点发生了变化后触发
        if(watchedEvent.getType() ==Event.EventType.NodeChildrenChanged){
            try {
                byte[] data = zooKeeper.getData("/lg_persistent/lg-children", true, null);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void createNode() throws KeeperException, InterruptedException {
        /*
        *   path :  创建的路径, 要以斜杠开头 (需要注意的是, 创建节点只能一级一级的创建)
        *   data[]: 要写入的数据, 是个字节数组
        *   acl :   权限信息:
        *               ZooDefs.Ids.ANYONE_ID_UNSAFE : 任何人
        *               ZooDefs.Ids.AUTH_IDS         : 此 ID 仅可用于设置 ACL
        *               ZooDefs.Ids.OPEN_ACL_UNSAFE  : 完全开放的 ACL: world:anyone
        *               ZooDefs.Ids.CREATOR_ALL_ACL  : 授予创建者 ACL 权限
        *   createMode: 创建节点的类型
        *
        *   返回的结果就是创建的路径字符串
        *
        *   String node = zookeeper.create(path,data,acl,createMode);
        */
        zooKeeper.create("/lagou", "hello world".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }

    private static void listNode() throws KeeperException, InterruptedException {
        List<String> children = zooKeeper.getChildren("/lagou", true);
        System.out.println(children);
    }

    private static void getData() throws KeeperException, InterruptedException, UnsupportedEncodingException {
        /*
        *   path  :  获取节点的路径
        *   watch :  是否要监听指定路径, 为 true 时会在子节点发生变化后触发 process 方法
        *            需要注意, 监听为一次性动作, 触发后, 如需继续触发, 需要重新注册一次监听
        *   stat  : 节点状态信息, null 表示最新数据
        */
        byte[] data = zooKeeper.getData("/lagou", true, null);
        System.out.println(new String(data,"utf-8"));
    }

    private static void updateNode() throws KeeperException, InterruptedException {
        /*
        *   path : 节点路径
        *   data : 节点数据
        *   version: 数据版本, -1 表示修改最新
        *
        */
        zooKeeper.setData("/lagou", "new data".getBytes(), -1);
    }

    private static void deleteNode() throws KeeperException, InterruptedException {
        Stat exist = zooKeeper.exists("/lagou", false);
        if (exist != null) {
            zooKeeper.delete("/lagou", -1);
        }
    }
}
